/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package managedbean.Finance;

import entity.Credit;
import entity.Customer;
import entity.Employee;
import entity.Invoice;
import entity.Job;
import entity.Payment;
import entity.PurchaseItem;
import entity.PurchaseOrder;
import entity.Receipt;
import entity.SalesOrder;
import entity.TrackingItem;
import entity.Warehouse;
import java.io.Serializable;
import java.sql.Timestamp;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import javax.ejb.EJB;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.RequestScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import managedbean.EmailManager;
import managedbean.UserSessionManagerBean;
import org.primefaces.event.SelectEvent;
import org.primefaces.event.UnselectEvent;
import session.stateless.CreditSessionBeanLocal;
import session.stateless.CustomerSessionBeanLocal;
import session.stateless.EmployeeSessionBeanLocal;
import session.stateless.LogSessionBeanLocal;
import session.stateless.MessageSessionBeanLocal;
import session.stateless.ProductionScheduleSessionBeanLocal;
import session.stateless.PurchaseOrderSessionBeanLocal;
import session.stateless.SalesOrderSessionBeanLocal;
import session.stateless.WarehouseSessionBeanLocal;

/**
 *
 * @author Wx
 */
@ManagedBean(name = "creditManagerBean")
@RequestScoped
public class CreditManagerBean implements Serializable {

    @EJB
    CreditSessionBeanLocal creditSessionBeanLocal;
    @EJB
    CustomerSessionBeanLocal customerSessionBeanLocal;
    @EJB
    SalesOrderSessionBeanLocal salesOrderSessionBeanLocal;
    @EJB
    EmployeeSessionBeanLocal employeeSessionBeanLocal;
    @EJB
    MessageSessionBeanLocal messageSessionBeanLocal;
    @EJB
    LogSessionBeanLocal logSessionBeanLocal;
    @EJB
    ProductionScheduleSessionBeanLocal productionScheduleSessionBeanLocal;
    @EJB
    PurchaseOrderSessionBeanLocal purchaseOrderSessionBeanLocal;
    @EJB
    WarehouseSessionBeanLocal warehouseSessionBeanLocal;
    @ManagedProperty(value = "#{userSessionManagerBean}")
    private UserSessionManagerBean userSessionManagerBean;
    private String loadReceipts;
    private String loadInvoices;
    private String loadPayments;
    private String loadAddCredit;
    private String loadUpdateCredit;
    private String loadViewCredit;
    private String loadCreditCheck;
    private String loadOutstandingInvoices;
    private Customer selectedCustomer;
    private Credit selectedCredit;
    //Credit
    private String remark;
    private Double creditScore; //paymentScore + outstandingScore + relationshipScore
    private String creditRank = ""; //Bronze, Silver, Gold, Pltinum, Titanium
    private Double creditLimit;
    private Double creditRate;
    private Double deposit;
    private Double balance;
    //40% of creditScore
    private Double paymentScore;
    private Integer totalPayments;
    private Integer paymentsPaidLessThan30;
    private Integer paymentsPaidLate30to59; //20% weightage of paymentScore
    private Integer paymentsPaidLate60to89; //30% weightage of paymentScore
    private Integer paymentsPaidLaterThan90; //50% weightage of paymentScore
    //40% of creditScore
    private Double outstandingScore;
    private Double totalAmount;
    private Double accountsPayable;
    //20% of creditScore
    private Double relationshipScore;
    private Integer yearsInBusiness;
    private Integer yearsOfDealings;
    //Credit Check
    private List<SalesOrder> salesOrders = new ArrayList<SalesOrder>();
    private SalesOrder selectedSalesOrder;
    private String result;
    private Boolean isNullSalesOrder;
    private Boolean hasOutstandingPayments;
    private List<Invoice> outstandingInvoices = new ArrayList<Invoice>();
    private List<Payment> payments = new ArrayList<Payment>();
    private Payment selectedPayment;
    private List<Invoice> invoices = new ArrayList<Invoice>();
    private Invoice selectedInvoice;
    private List<Receipt> receipts = new ArrayList<Receipt>();
    private Receipt selectedReceipt;
    private Timestamp todayTimestampMinus30;
    private Timestamp todayTimestampMinus7;

    /** Creates a new instance of CreditManagerBean */
    public CreditManagerBean() {
    }

    public void invoicesRowSelectListener(SelectEvent event) {
        userSessionManagerBean.setSelectedItem(selectedInvoice);
    }

    public void receiptsRowSelectListener(SelectEvent event) {
        userSessionManagerBean.setSelectedItem(selectedReceipt);
    }

    /**
     * @return the loadCreditCheck
     */
    public String getLoadCreditCheck() {
        selectedCustomer = userSessionManagerBean.getCustomer();
        isNullSalesOrder = true;
        hasOutstandingPayments = false;

        List<SalesOrder> temp = salesOrderSessionBeanLocal.getSalesOrders("Pending Credit Check");

        for (SalesOrder so : temp) {
            if (so.getJob().getCustomer().getId() == selectedCustomer.getCustId()) {
                salesOrders.add(so);
            }
        }

        checkOutstandingPayments(selectedCustomer);

        return null;
    }

    public void checkOutstandingPayments(Customer customer) {
        List<SalesOrder> temp = salesOrderSessionBeanLocal.getSalesOrders("Pending Deliveries and Payments");

        for (SalesOrder so : temp) {
            Job job = so.getJob();

            if (job.getCustomer().getId() == customer.getCustId()) {
                PurchaseOrder po = job.getPurchaseOrder();

                for (PurchaseItem pi : po.getPurchaseItems()) { //get all invoices that are pending payment
                    Invoice invoice = creditSessionBeanLocal.getInvoice(pi.getId(), "Pending Payment");

                    if (invoice != null) {
                        outstandingInvoices.add(invoice);
                    }
                }
            }
        }

        if (outstandingInvoices.size() > 0) { //if there are outstanding invoices pending payment
            hasOutstandingPayments = true;
        }
    }

    /**
     * @param loadCreditCheck the loadCreditCheck to set
     */
    public void setLoadCreditCheck(String loadCreditCheck) {
        this.loadCreditCheck = loadCreditCheck;
    }

    /**
     * @return the loadAddCredit
     */
    public String getLoadAddCredit() {
        selectedCustomer = getUserSessionManagerBean().getCustomer();

        creditRank = "";
        totalPayments = 0;
        paymentsPaidLessThan30 = 0;
        paymentsPaidLate30to59 = 0;
        paymentsPaidLate60to89 = 0;
        paymentsPaidLaterThan90 = 0;
        totalAmount = 0.0;
        accountsPayable = 0.0;
        outstandingScore = 0.0;
        relationshipScore = 0.0;
        yearsInBusiness = 0;
        yearsOfDealings = 0;
        paymentScore = 0.0;
        creditScore = 0.0;

        return null;
    }

    /**
     * @param loadAddCredit the loadAddCredit to set
     */
    public void setLoadAddCredit(String loadAddCredit) {
        this.loadAddCredit = loadAddCredit;
    }

    /**
     * @return the loadUpdateCredit
     */
    public String getLoadUpdateCredit() {
        loadInfo();

        return null;
    }

    /**
     * @return the loadViewCredit
     */
    public String getLoadViewCredit() {
        loadInfo();

        return null;
    }

    /**
     * @param loadViewCredit the loadViewCredit to set
     */
    public void setLoadViewCredit(String loadViewCredit) {
        this.loadViewCredit = loadViewCredit;
    }

    /**
     * @param loadUpdateCredit the loadUpdateCredit to set
     */
    public void setLoadUpdateCredit(String loadUpdateCredit) {
        this.loadUpdateCredit = loadUpdateCredit;
    }

    public void loadInfo() {
        selectedCustomer = getUserSessionManagerBean().getCustomer();
        selectedCredit = selectedCustomer.getCredit();

        remark = selectedCredit.getRemark();
        creditScore = selectedCredit.getCreditScore();
        creditRank = selectedCredit.getCreditRank();

        paymentScore = selectedCredit.getPaymentScore();
        totalPayments = selectedCredit.getTotalPayments();
        paymentsPaidLessThan30 = selectedCredit.getPaymentsPaidLessThan30();
        paymentsPaidLate30to59 = selectedCredit.getPaymentsPaidLate30to59();
        paymentsPaidLate60to89 = selectedCredit.getPaymentsPaidLate60to89();
        paymentsPaidLaterThan90 = selectedCredit.getPaymentsPaidLaterThan90();

        outstandingScore = selectedCredit.getOutstandingScore();
        totalAmount = selectedCredit.getTotalAmount();
        accountsPayable = selectedCredit.getAccountsPayable();

        relationshipScore = selectedCredit.getRelationshipScore();
        yearsInBusiness = selectedCredit.getYearsInBusiness();
        yearsOfDealings = selectedCredit.getYearsOfDealings();
    }

    /**
     * @return the selectedCustomer
     */
    public Customer getSelectedCustomer() {
        return selectedCustomer;
    }

    /**
     * @param selectedCustomer the selectedCustomer to set
     */
    public void setSelectedCustomer(Customer selectedCustomer) {
        this.selectedCustomer = selectedCustomer;
    }

    /**
     * @return the remark
     */
    public String getRemark() {
        return remark;
    }

    /**
     * @param remark the remark to set
     */
    public void setRemark(String remark) {
        this.remark = remark;
    }

    /**
     * @return the creditScore
     */
    public Double getCreditScore() {
        return creditScore;
    }

    /**
     * @param creditScore the creditScore to set
     */
    public void setCreditScore(Double creditScore) {
        this.creditScore = creditScore;
    }

    /**
     * @return the creditRank
     */
    public String getCreditRank() {
        return creditRank;
    }

    /**
     * @param creditRank the creditRank to set
     */
    public void setCreditRank(String creditRank) {
        this.creditRank = creditRank;
    }

    /**
     * @return the paymentScore
     */
    public Double getPaymentScore() {
        return paymentScore;
    }

    /**
     * @param paymentScore the paymentScore to set
     */
    public void setPaymentScore(Double paymentScore) {
        this.paymentScore = paymentScore;
    }

    /**
     * @return the totalLoans
     */
    public Integer getTotalPayments() {
        return totalPayments;
    }

    /**
     * @param totalLoans the totalLoans to set
     */
    public void setTotalPayments(Integer totalPayments) {
        this.totalPayments = totalPayments;
    }

    /**
     * @return the loansPaidLessThan29
     */
    public Integer getPaymentsPaidLessThan30() {
        return paymentsPaidLessThan30;
    }

    /**
     * @param loansPaidLessThan29 the loansPaidLessThan29 to set
     */
    public void setPaymentsPaidLessThan30(Integer paymentsPaidLessThan30) {
        this.paymentsPaidLessThan30 = paymentsPaidLessThan30;
    }

    /**
     * @return the loansPaidLate30to59
     */
    public Integer getPaymentsPaidLate30to59() {
        return paymentsPaidLate30to59;
    }

    /**
     * @param loansPaidLate30to59 the loansPaidLate30to59 to set
     */
    public void setPaymentsPaidLate30to59(Integer paymentsPaidLate30to59) {
        this.paymentsPaidLate30to59 = paymentsPaidLate30to59;
    }

    /**
     * @return the loansPaidLaterThan90
     */
    public Integer getPaymentsPaidLaterThan90() {
        return paymentsPaidLaterThan90;
    }

    /**
     * @param loansPaidLaterThan90 the loansPaidLaterThan90 to set
     */
    public void setPaymentsPaidLaterThan90(Integer paymentsPaidLaterThan90) {
        this.paymentsPaidLaterThan90 = paymentsPaidLaterThan90;
    }

    /**
     * @return the outstandingScore
     */
    public Double getOutstandingScore() {
        return outstandingScore;
    }

    /**
     * @param outstandingScore the outstandingScore to set
     */
    public void setOutstandingScore(Double outstandingScore) {
        this.outstandingScore = outstandingScore;
    }

    /**
     * @return the totalAmount
     */
    public Double getTotalAmount() {
        return totalAmount;
    }

    /**
     * @param totalAmount the totalAmount to set
     */
    public void setTotalAmount(Double totalAmount) {
        this.totalAmount = totalAmount;
    }

    /**
     * @return the accountsPayable
     */
    public Double getAccountsPayable() {
        return accountsPayable;
    }

    /**
     * @param outstandingAmount the accountsPayable to set
     */
    public void setAccountsPayable(Double accountsPayable) {
        this.accountsPayable = accountsPayable;
    }

    /**
     * @return the relationshipScore
     */
    public Double getRelationshipScore() {
        return relationshipScore;
    }

    /**
     * @param relationshipScore the relationshipScore to set
     */
    public void setRelationshipScore(Double relationshipScore) {
        this.relationshipScore = relationshipScore;
    }

    /**
     * @return the yearsInBusiness
     */
    public Integer getYearsInBusiness() {
        return yearsInBusiness;
    }

    /**
     * @param yearsInBusiness the yearsInBusiness to set
     */
    public void setYearsInBusiness(Integer yearsInBusiness) {
        this.yearsInBusiness = yearsInBusiness;
    }

    /**
     * @return the yearsOfDealings
     */
    public Integer getYearsOfDealings() {
        return yearsOfDealings;
    }

    /**
     * @param yearsOfDealings the yearsOfDealings to set
     */
    public void setYearsOfDealings(Integer yearsOfDealings) {
        this.yearsOfDealings = yearsOfDealings;
    }

    public void compute() {
        //for relationshipScore
        double num8 = yearsInBusiness;
        double num9 = yearsOfDealings;

        if (num9 > num8) {
            relationshipScore = round(0.00, 2);
        } else {
            double num98 = (num9 / num8) * 100;
            relationshipScore = 0.2 * num98;
            relationshipScore = round(relationshipScore, 2);
        }

        creditScore = paymentScore + outstandingScore + relationshipScore;
        creditScore = round(creditScore, 2);
    }

    public double round(double valueToRound, int numberOfDecimalPlaces) {
        double multiplicationFactor = Math.pow(10, numberOfDecimalPlaces);
        double interestedInZeroDPs = valueToRound * multiplicationFactor;

        return Math.round(interestedInZeroDPs) / multiplicationFactor;
    }

    public void save(ActionEvent e) {
        try {
            if (!e.getComponent().getId().equals("btnDoneView")) {
                if (creditRank != null && !creditRank.equals("")) { //if a credit rank is selected
                    if (yearsOfDealings <= yearsInBusiness) { //if years of dealings with us <= years in business
                        if (paymentScore != Double.NaN && outstandingScore != Double.NaN && relationshipScore != Double.NaN) { //if paymentScore and outstandScore and relationshipScore are computed correctly

                            compute(); //calculate scores again

                            if (creditRank.equals("Blacklisted")) {
                                creditLimit = 0.00;
                                creditRate = 0.00;
                            } else if (creditRank.equals("Bronze")) {
                                creditLimit = 0.00;
                                creditRate = 0.00;
                            } else if (creditRank.equals("Silver")) {
                                creditLimit = 50000.00;
                                creditRate = 0.1;
                            } else if (creditRank.equals("Gold")) {
                                creditLimit = 100000.00;
                                creditRate = 0.1;
                            } else if (creditRank.equals("Platinum")) {
                                creditLimit = 150000.00;
                                creditRate = 0.2;
                            } else if (creditRank.equals("Titanium")) {
                                creditLimit = 200000.00;
                                creditRate = 0.3;
                            }

                            deposit = 0.00;
                            balance = 0.00;

                            Credit temp = new Credit(remark, creditScore, creditRank, paymentScore, totalPayments, paymentsPaidLessThan30,
                                    paymentsPaidLate30to59, paymentsPaidLate60to89, paymentsPaidLaterThan90, outstandingScore,
                                    totalAmount, accountsPayable, relationshipScore, yearsInBusiness, yearsOfDealings,
                                    creditLimit, deposit, balance, null, creditRate);

                            if (e.getComponent().getId().equals("btnAddCredit")) { //adding credit for customer
                                creditSessionBeanLocal.addCredit(selectedCustomer.getCustId(), temp);

                                selectedCustomer = customerSessionBeanLocal.getCustomer(selectedCustomer.getCustId());

                                userSessionManagerBean.setCustomer(selectedCustomer);

                                //sucess page content
                                ArrayList<String> al = new ArrayList<String>();
                                al.add("Credit record");
                                al.add("You have successfully created the credit record.");
                                al.add("Click on the link to to ");
                                al.add("continue");
                                al.add("Web_Sales/searchCustomer.xhtml?request=updateCredit");
                                userSessionManagerBean.setSelectedItem(al);

                                //log
                                logSessionBeanLocal.addLog("Add credit", "Credit record created: " + userSessionManagerBean.getUserId(), "addCredit.xhtml", userSessionManagerBean.getUserId());
                            } else { //updating existing credit information
                                creditSessionBeanLocal.updateCredit(selectedCredit.getId(), temp);

                                selectedCustomer = customerSessionBeanLocal.getCustomer(selectedCustomer.getCustId());

                                userSessionManagerBean.setCustomer(selectedCustomer);

                                //sucess page content
                                ArrayList<String> al = new ArrayList<String>();
                                al.add("Credit record");
                                al.add("You have successfully updated the credit record.");
                                al.add("Click on the link to to ");
                                al.add("continue");
                                al.add("Web_Sales/searchCustomer.xhtml?request=updateCredit");
                                userSessionManagerBean.setSelectedItem(al);

                                //log
                                logSessionBeanLocal.addLog("Update credit", "Credit record updated: " + userSessionManagerBean.getUserId(), "updateCredit.xhtml", userSessionManagerBean.getUserId());
                            }

                            //redirect to success page
                            FacesContext.getCurrentInstance().getExternalContext().redirect("http://"
                                    + userSessionManagerBean.getServerName() + ":"
                                    + userSessionManagerBean.getServerPort()
                                    + "/MerlionERP-war/success.xhtml");
                        } else {
                            FacesContext.getCurrentInstance().addMessage(null,
                                    new FacesMessage(FacesMessage.SEVERITY_ERROR, "Invalid figures entered. Figures entered must be whole numbers.", ""));
                        }
                    } else {
                        FacesContext.getCurrentInstance().addMessage(null,
                                new FacesMessage(FacesMessage.SEVERITY_ERROR, "Customer's years of dealings with us cannot be more than their years in business.", ""));
                    }
                } else {
                    FacesContext.getCurrentInstance().addMessage(null,
                            new FacesMessage(FacesMessage.SEVERITY_ERROR, "A credit rank must be given to the customer.", ""));
                }
            } else {
                FacesContext.getCurrentInstance().getExternalContext().redirect("http://"
                        + getUserSessionManagerBean().getServerName() + ":"
                        + getUserSessionManagerBean().getServerPort()
                        + "/MerlionERP-war/Web_Sales/searchCustomer.xhtml?request=viewCredit"); //redirect to searchCustomer.xhtml
            }
        } catch (Exception ex) {
            FacesContext.getCurrentInstance().addMessage(null,
                    new FacesMessage(FacesMessage.SEVERITY_ERROR, ex.toString(), ""));
            ex.printStackTrace();
        }
    }

    /**
     * @return the selectedCredit
     */
    public Credit getSelectedCredit() {
        return selectedCredit;
    }

    /**
     * @param selectedCredit the selectedCredit to set
     */
    public void setSelectedCredit(Credit selectedCredit) {
        this.selectedCredit = selectedCredit;
    }

    /**
     * @return the userSessionManagerBean
     */
    public UserSessionManagerBean getUserSessionManagerBean() {
        return userSessionManagerBean;
    }

    /**
     * @param userSessionManagerBean the userSessionManagerBean to set
     */
    public void setUserSessionManagerBean(UserSessionManagerBean userSessionManagerBean) {
        this.userSessionManagerBean = userSessionManagerBean;
    }

    /**
     * @return the creditLimit
     */
    public Double getCreditLimit() {
        return creditLimit;
    }

    /**
     * @param creditLimit the creditLimit to set
     */
    public void setCreditLimit(Double creditLimit) {
        this.creditLimit = creditLimit;
    }

    /**
     * @return the deposit
     */
    public Double getDeposit() {
        return deposit;
    }

    /**
     * @param deposit the deposit to set
     */
    public void setDeposit(Double deposit) {
        this.deposit = deposit;
    }

    /**
     * @return the balance
     */
    public Double getBalance() {
        return balance;
    }

    /**
     * @param balance the balance to set
     */
    public void setBalance(Double balance) {
        this.balance = balance;
    }

    /**
     * @return the payments
     */
    public List<Payment> getPayments() {
        return payments;
    }

    /**
     * @param payments the payments to set
     */
    public void setPayments(List<Payment> payments) {
        this.payments = payments;
    }

    /**
     * @return the salesOrders
     */
    public List<SalesOrder> getSalesOrders() {
        return salesOrders;
    }

    /**
     * @param salesOrders the salesOrders to set
     */
    public void setSalesOrders(List<SalesOrder> salesOrders) {
        this.salesOrders = salesOrders;
    }

    /**
     * @return the selectedSalesOrder
     */
    public SalesOrder getSelectedSalesOrder() {
        return selectedSalesOrder;
    }

    /**
     * @param selectedSalesOrder the selectedSalesOrder to set
     */
    public void setSelectedSalesOrder(SalesOrder selectedSalesOrder) {
        this.selectedSalesOrder = selectedSalesOrder;
    }

    public void onRowSelect(SelectEvent event) { //on row select of the customer's orders
        result = "";
        result += "Credit check status: ";

        if (hasOutstandingPayments) { //if customer has outstanding payments
            result += "\nCustomer has outstanding payments, therefore his credit check cannot be passed.";
            result += "\nInvoices in question are: ";

            for (Invoice i : outstandingInvoices) {
                result += i.getId() + " ";
            }

            result += "\nFail the credit check to inform the customer to clear off his outstanding payments first.";

            isNullSalesOrder = false;
        } else { //if customer does not have any outstanding payments
            Job j = selectedSalesOrder.getJob();
            PurchaseOrder po = j.getPurchaseOrder();
            Credit c = selectedCustomer.getCredit();

            if (c != null) { //customer has a credit account already
                NumberFormat nf = NumberFormat.getCurrencyInstance();
                NumberFormat nf2 = NumberFormat.getPercentInstance();

                result += "\nCustomer's current credit limit is " + nf.format(c.getCreditLimit()) + ".";
                result += "\nCustomer's current outstanding payment amount is " + nf.format(c.getAccountsPayable()) + ".\n";

                Double poCreditRate = po.getCreditRate() / 100;
                Double creditAmount = poCreditRate * po.getTotalAmount();

                result += "\nThe purchase order requests a credit rate of " + nf2.format(poCreditRate) + ".";
                result += "\nThe customer's credit rate is " + nf2.format(c.getCreditRate()) + ".\n";

                result += "\nThis order requires an additional credit of " + nf.format(creditAmount) + ".";
                if (c.getCreditLimit() <= c.getAccountsPayable() + creditAmount) {
                    result += "\nCustomer's outstanding payment will exceed his credit limit after credit check is passed.\n";
                    result += "\nRecommendation:\nReject Sales Order";
                } else {
                    result += "\nCustomer's outstanding payment will still be below credit limit after approval.\n";
                    result += "\nRecommendation:\nApprove Sales Order";
                }
                isNullSalesOrder = false;
            } else { //customer does not have a credit account yet
                result += "\nCustomer does not have a credit account yet, please proceed to create one for him before continuing.";
                isNullSalesOrder = true;
            }
        }
    }

    public void onRowUnselect(UnselectEvent event) { //on row unselect of the customer's orders
        selectedSalesOrder = null;
        isNullSalesOrder = true;
        result = "";
    }

    /**
     * @return the status
     */
    public String getResult() {
        return result;
    }

    /**
     * @param status the status to set
     */
    public void setResult(String result) {
        this.result = result;
    }

    public void passCreditCheck(ActionEvent e) {
        if (selectedSalesOrder != null) {
            try {
                salesOrderSessionBeanLocal.passSalesOrderCreditCheck(selectedSalesOrder.getId()); //pass the credit check

                TrackingItem ti = new TrackingItem();
                ti.setDescription("Sales Order Passed Credit Check");

                //add ti to sales order's tracking items
                salesOrderSessionBeanLocal.updateSalesOrder(selectedSalesOrder.getId(), ti);

                PurchaseOrder selectedPurchaseOrder = selectedSalesOrder.getJob().getPurchaseOrder();

                salesOrderSessionBeanLocal.updateSalesOrder(selectedSalesOrder.getId(), "Pending Deliveries and Payments");

                Customer customer = selectedSalesOrder.getJob().getCustomer();
                Credit credit = customer.getCredit(); //get customer's credit info

                //add to current total amount
                credit.setTotalAmount(credit.getTotalAmount() + selectedPurchaseOrder.getTotalAmount());

                //add to current accounts payable
                credit.setAccountsPayable(credit.getAccountsPayable() + selectedPurchaseOrder.getTotalAmount());

                //start of recalculation of credit's outstandingScore and creditScore
                double num6 = credit.getTotalAmount();
                double num7 = credit.getAccountsPayable();
                double outstandingScore2 = 0.0;
                double creditScore2 = credit.getCreditScore();

                creditScore2 -= credit.getOutstandingScore();

                if (num7 > num6) {
                    outstandingScore2 = round(0.00, 2);
                } else {
                    double num76 = (num7 / num6) * 100;
                    num76 = 100 - num76;
                    outstandingScore2 = 0.4 * num76;
                    outstandingScore2 = round(outstandingScore2, 2);
                }

                creditScore2 += outstandingScore2;
                creditScore2 = round(creditScore2, 2);

                credit.setCreditScore(creditScore2);
                credit.setOutstandingScore(outstandingScore2);
                //end of recalculation of credit's outstandingScore and creditScore

                creditSessionBeanLocal.updateCredit(credit.getId(), credit); //update credit

                EmailManager em = new EmailManager();
                for (PurchaseItem poi : selectedSalesOrder.getJob().getPurchaseOrder().getPurchaseItems()) {
                    Double outstanding = selectedPurchaseOrder.getCreditRate() / 100; //10 = 0.1
                    Double outstandingAmount = poi.getSubTotal(); //purchase item's outstanding amount
                    Double amount = 1.00 - outstanding; //1 - 0.1 = 0.9
                    Double amountToPay = amount * poi.getSubTotal(); //purchase item's amount to pay = % * subTotal

                    amountToPay = round(amountToPay, 2);

                    Calendar cal = Calendar.getInstance();
                    Timestamp ts = new Timestamp(cal.getTime().getTime());

                    Invoice invoice = new Invoice(ts, amountToPay, poi, "Pending Payment", "Advance Payment");

                    creditSessionBeanLocal.updateCredit(credit.getId(), invoice);

                    creditSessionBeanLocal.updatePurchaseItem(poi.getId(), outstandingAmount, "Pending Advance Payment");
                }

                for (PurchaseItem poi : selectedSalesOrder.getJob().getPurchaseOrder().getPurchaseItems()) {
                    Double outstanding = selectedPurchaseOrder.getCreditRate() / 100; //10 = 0.1
                    Double outstandingAmount = poi.getSubTotal(); //purchase item's outstanding amount
                    Double amount = 1.00 - outstanding; //1 - 0.1 = 0.9
                    Double amountToPay = amount * poi.getSubTotal(); //purchase item's amount to pay = % * subTotal

                    amountToPay = round(amountToPay, 2);

                    //start of send invoice to customer
                    String subject = "Invoice for Advance Payment";

                    String msg = "Dear " + customer.getCompany() + ",\n\n";

                    Invoice invoice = creditSessionBeanLocal.getInvoice(poi.getId(), "Pending Payment", "Advance Payment");

                    msg += "Invoice No.: " + invoice.getId() + "\n";

                    SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");
                    StringBuilder sb = new StringBuilder(sdf.format(invoice.getInvoiceDate()));

                    msg += "Invoice Date: " + sb + "\n";
                    msg += "Purchase Item: " + poi.getProduct().getName() + "\n";
                    msg += "Purchase Quantity: " + poi.getQuantity() + "\n";

                    NumberFormat nf = NumberFormat.getCurrencyInstance();

                    msg += "Amount to Pay: " + nf.format(amountToPay) + "\n";
                    msg += "Remarks: Please remember to make payment within 30 days after the invoice date.\n\n";
                    msg += "Regards,\nMerlion Food Limited";

                    String sender = "mf.merlionerp@gmail.com";
                    String receiver = customer.getEmail();
                    String password = "merlionfood";

                    System.out.println("Sending invoice to " + receiver + "...");

                    em.sendEmail(subject, msg, sender, receiver, password);
                    //end of send invoice to customer
                }

                //start of ATP CHECK
                Warehouse wh = warehouseSessionBeanLocal.getWarehouse(Long.parseLong("1000"));
                Boolean passATP = productionScheduleSessionBeanLocal.ATPCheck(wh,
                        purchaseOrderSessionBeanLocal.sortPurchaseItems(new ArrayList(selectedPurchaseOrder.getPurchaseItems())),
                        productionScheduleSessionBeanLocal.getProductionSchedules());
                //end of ATP CHECK
                System.out.println("ATP CHECK -> " + passATP);
                if (passATP) {
                    for (PurchaseItem poi : selectedSalesOrder.getJob().getPurchaseOrder().getPurchaseItems()) {
                        productionScheduleSessionBeanLocal.reservePurchaseItem(wh, poi.getId(), productionScheduleSessionBeanLocal.getProductionSchedules());
                        purchaseOrderSessionBeanLocal.updatePurchaseItemStatus(poi.getId(), "Pending for Shipping");
                    }

                    ti = new TrackingItem();
                    ti.setDescription("Production scheduled");

                    salesOrderSessionBeanLocal.updateSalesOrder(selectedSalesOrder.getId(), ti);
                    salesOrderSessionBeanLocal.updateAtpStatus(selectedSalesOrder.getId(), "Passed");

                    //start of finance - NEED TO MOVE TO AFTER ATP CHECK PASSED
                    // salesOrderSessionBeanLocal.updateSalesOrder(selectedSalesOrder.getId(), "Pending Deliveries and Payments");

//                    Customer customer = selectedSalesOrder.getJob().getCustomer();
//                    Credit credit = customer.getCredit(); //get customer's credit info
//
//                    //add to current total amount
//                    credit.setTotalAmount(credit.getTotalAmount() + selectedPurchaseOrder.getTotalAmount());
//
//                    //add to current accounts payable
//                    credit.setAccountsPayable(credit.getAccountsPayable() + selectedPurchaseOrder.getTotalAmount());
//
//                    //start of recalculation of credit's outstandingScore and creditScore
//                    double num6 = credit.getTotalAmount();
//                    double num7 = credit.getAccountsPayable();
//                    double outstandingScore2 = 0.0;
//                    double creditScore2 = credit.getCreditScore();
//
//                    creditScore2 -= credit.getOutstandingScore();
//
//                    if (num7 > num6) {
//                        outstandingScore2 = round(0.00, 2);
//                    } else {
//                        double num76 = (num7 / num6) * 100;
//                        num76 = 100 - num76;
//                        outstandingScore2 = 0.4 * num76;
//                        outstandingScore2 = round(outstandingScore2, 2);
//                    }
//
//                    creditScore2 += outstandingScore2;
//                    creditScore2 = round(creditScore2, 2);
//
//                    credit.setCreditScore(creditScore2);
//                    credit.setOutstandingScore(outstandingScore2);
//                    //end of recalculation of credit's outstandingScore and creditScore
//
//                    creditSessionBeanLocal.updateCredit(credit.getId(), credit); //update credit

//                    EmailManager em = new EmailManager();
//                    for (PurchaseItem poi : selectedSalesOrder.getJob().getPurchaseOrder().getPurchaseItems()) {
//                        Double outstanding = selectedPurchaseOrder.getCreditRate() / 100; //10 = 0.1
//                        Double outstandingAmount = poi.getSubTotal(); //purchase item's outstanding amount
//                        Double amount = 1.00 - outstanding; //1 - 0.1 = 0.9
//                        Double amountToPay = amount * poi.getSubTotal(); //purchase item's amount to pay = % * subTotal
//
//                        amountToPay = round(amountToPay, 2);
//
//                        Calendar cal = Calendar.getInstance();
//                        Timestamp ts = new Timestamp(cal.getTime().getTime());
//
//                        Invoice invoice = new Invoice(ts, amountToPay, poi, "Pending Payment", "Advance Payment");
//
//                        creditSessionBeanLocal.updateCredit(credit.getId(), invoice);
//
//                        creditSessionBeanLocal.updatePurchaseItem(poi.getId(), outstandingAmount, "Pending Advance Payment");
//                    }
//
//                    for (PurchaseItem poi : selectedSalesOrder.getJob().getPurchaseOrder().getPurchaseItems()) {
//                        Double outstanding = selectedPurchaseOrder.getCreditRate() / 100; //10 = 0.1
//                        Double outstandingAmount = poi.getSubTotal(); //purchase item's outstanding amount
//                        Double amount = 1.00 - outstanding; //1 - 0.1 = 0.9
//                        Double amountToPay = amount * poi.getSubTotal(); //purchase item's amount to pay = % * subTotal
//
//                        amountToPay = round(amountToPay, 2);
//
//                        //start of send invoice to customer
//                        String subject = "Invoice for Advance Payment";
//
//                        String msg = "Dear " + customer.getCompany() + ",\n\n";
//
//                        Invoice invoice = creditSessionBeanLocal.getInvoice(poi.getId(), "Pending Payment", "Advance Payment");
//
//                        msg += "Invoice No.: " + invoice.getId() + "\n";
//
//                        SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");
//                        StringBuilder sb = new StringBuilder(sdf.format(invoice.getInvoiceDate()));
//
//                        msg += "Invoice Date: " + sb + "\n";
//                        msg += "Purchase Item: " + poi.getProduct().getName() + "\n";
//                        msg += "Purchase Quantity: " + poi.getQuantity() + "\n";
//
//                        NumberFormat nf = NumberFormat.getCurrencyInstance();
//
//                        msg += "Amount to Pay: " + nf.format(amountToPay) + "\n";
//                        msg += "Remarks: Please remember to make payment within 30 days after the invoice date.\n\n";
//                        msg += "Regards,\nMerlion Food Limited";
//
//                        String sender = "mf.merlionerp@gmail.com";
//                        String receiver = customer.getEmail();
//                        String password = "merlionfood";
//
//                        System.out.println("Sending invoice to " + receiver + "...");
//
//                        em.sendEmail(subject, msg, sender, receiver, password);
//                        //end of send invoice to customer
//                    }
                } else {
                    salesOrderSessionBeanLocal.updateAtpStatus(selectedSalesOrder.getId(), "Failed");

                    Employee owner = employeeSessionBeanLocal.getEmployee("System");
                    messageSessionBeanLocal.addMessage("System", selectedSalesOrder.getJob().getEmployee().getUserId(), "ATP Failed",
                            "Job: " + selectedSalesOrder.getJob().getJobId() + " has failed ATP check. "
                            + "Please reconfirm the shipping date with the customer." + "<br>", owner);

                    owner = employeeSessionBeanLocal.getEmployee(selectedSalesOrder.getJob().getEmployee().getUserId());
                    messageSessionBeanLocal.addMessage("System", selectedSalesOrder.getJob().getEmployee().getUserId(), "ATP Failed",
                            "Job: " + selectedSalesOrder.getJob().getJobId() + " has failed ATP check. "
                            + "Please reconfirm the shipping date with the customer." + "<br>", owner);
                }
                //end of finance 

                //start of notify sales executive and log
                Customer c = selectedSalesOrder.getJob().getCustomer();

                String userid1 = c.getEmployee().getUserId();
                String userId2 = userSessionManagerBean.getUserId();

                Employee financeUser = employeeSessionBeanLocal.getEmployee(userId2);

                Employee owner = employeeSessionBeanLocal.getEmployee("System");
                messageSessionBeanLocal.addMessage("System", userid1, "Credit Check Passed",
                        "Customer: " + c.getCompany() + "<br>"
                        + "Job ID: " + selectedSalesOrder.getJob().getJobId() + "</b><br>"
                        + "By: <b>" + financeUser.getName(), owner);

                owner = employeeSessionBeanLocal.getEmployee(userid1);
                messageSessionBeanLocal.addMessage("System", userid1, "Credit Check Passed", //to send message to executive
                        "Customer: " + c.getCompany() + "<br>"
                        + "Job ID: " + selectedSalesOrder.getJob().getJobId() + "<br>"
                        + "By: " + financeUser.getName(), owner);

                logSessionBeanLocal.addLog("Credit Check", "Passed credit check: Customer " + c.getCompany() + "'s order with job id of "
                        + selectedSalesOrder.getJob().getJobId() + " has been passed its credit check by finance user "
                        + financeUser.getUserId() + ".", "creditCheck.xhtml", financeUser.getUserId());
                //end of notify sales executive and log

                FacesContext.getCurrentInstance().getExternalContext().redirect("http://"
                        + getUserSessionManagerBean().getServerName() + ":"
                        + getUserSessionManagerBean().getServerPort()
                        + "/MerlionERP-war/Web_Sales/searchCustomer.xhtml?request=creditCheck"); //redirect to searchCustomer.xhtml
            } catch (Exception ex) {
                ex.printStackTrace();
                FacesContext.getCurrentInstance().addMessage(null,
                        new FacesMessage(FacesMessage.SEVERITY_ERROR, ex.toString(), ""));
            }
        } else {
            FacesContext.getCurrentInstance().addMessage(null,
                    new FacesMessage(FacesMessage.SEVERITY_ERROR, "Please select a sales order before continuing.", ""));
        }
    }

    public void failCreditCheck(ActionEvent e) {
        if (selectedSalesOrder != null) {
            try {
                salesOrderSessionBeanLocal.failSalesOrderCreditCheck(selectedSalesOrder.getId()); //fail the credit check

                //start of notify sales executive and log
                Customer c = selectedSalesOrder.getJob().getCustomer();

                String userid1 = c.getEmployee().getUserId();
                String userId2 = userSessionManagerBean.getUserId();

                Employee financeUser = employeeSessionBeanLocal.getEmployee(userId2);

                Employee owner = employeeSessionBeanLocal.getEmployee("System");
                messageSessionBeanLocal.addMessage("System", userid1, "Credit Check Failed",
                        "Customer: " + c.getCompany() + "<br>"
                        + "Job ID: " + selectedSalesOrder.getJob().getJobId() + "<br>"
                        + "By: " + financeUser.getName() + "<br>"
                        + "Please advise the customer to:<br>"
                        + " - pay off existing invoices, or<br>"
                        + " - pay partial or full amount in advance for the order, or<br>"
                        + " - reduce order amount.", owner);

                owner = employeeSessionBeanLocal.getEmployee(userid1);
                messageSessionBeanLocal.addMessage("System", userid1, "Credit Check Failed", //to send message to executive
                        "Customer: <b>" + c.getCompany() + "</b><br>"
                        + "Job ID: <b>" + selectedSalesOrder.getJob().getJobId() + "</b><br>"
                        + "By: <b>" + financeUser.getName() + "</b><br>"
                        + "Please advise the customer to:<br>"
                        + " - pay off existing invoices, or<br>"
                        + " - pay partial or full amount in advance for the order, or<br>"
                        + " - reduce order amount.", owner);

                logSessionBeanLocal.addLog("Credit Check", "Failed credit check: Customer " + c.getCompany() + "'s order with job id of "
                        + selectedSalesOrder.getJob().getJobId() + " has been failed its credit check by finance user "
                        + financeUser.getUserId() + ".", "creditCheck.xhtml", financeUser.getUserId());
                //end of notify sales executive and log

                if (hasOutstandingPayments) { //if customer has outstanding payments, send email to notify them
                    EmailManager em = new EmailManager();

                    String subject = "Reminder to Settle Existing Invoices";
                    String sender = "mf.merlionerp@gmail.com";
                    String receiver = c.getEmail();
                    String password = "merlionfood";

                    String msg = "Dear " + c.getCompany() + ",\n\n";
                    msg += "Please settle your outstanding invoices before making another order. \n\nWe will not process your new orders until you do so.\n\n";
                    msg += "Invoices in question are: ";

                    for (Invoice i : outstandingInvoices) {
                        msg += i.getId() + " ";
                    }

                    msg += "\n\n";
                    msg += "Regards,\n";
                    msg += "Merlion Food Limited";

                    System.out.println("Sending credit reminders to " + receiver + "...");

                    em.sendEmail(subject, msg, sender, receiver, password);
                }

                FacesContext.getCurrentInstance().getExternalContext().redirect("http://"
                        + getUserSessionManagerBean().getServerName() + ":"
                        + getUserSessionManagerBean().getServerPort()
                        + "/MerlionERP-war/Web_Sales/searchCustomer.xhtml?request=creditCheck"); //redirect to searchCustomer.xhtml
            } catch (Exception ex) {
                FacesContext.getCurrentInstance().addMessage(null,
                        new FacesMessage(FacesMessage.SEVERITY_ERROR, ex.toString(), ""));
            }
        } else {
            FacesContext.getCurrentInstance().addMessage(null,
                    new FacesMessage(FacesMessage.SEVERITY_ERROR, "Please select a sales order before continuing.", ""));
        }
    }

    /**
     * @return the isNullSalesOrder
     */
    public Boolean getIsNullSalesOrder() {
        return isNullSalesOrder;
    }

    /**
     * @param isNullSalesOrder the isNullSalesOrder to set
     */
    public void setIsNullSalesOrder(Boolean isNullSalesOrder) {
        this.isNullSalesOrder = isNullSalesOrder;
    }

    /**
     * @return the paymentsPaidLate60to89
     */
    public Integer getPaymentsPaidLate60to89() {
        return paymentsPaidLate60to89;
    }

    /**
     * @param paymentsPaidLate60to89 the paymentsPaidLate60to89 to set
     */
    public void setPaymentsPaidLate60to89(Integer paymentsPaidLate60to89) {
        this.paymentsPaidLate60to89 = paymentsPaidLate60to89;
    }

    /**
     * @return the hasOutstandingPayments
     */
    public Boolean getHasOutstandingPayments() {
        return hasOutstandingPayments;
    }

    /**
     * @param hasOutstandingPayments the hasOutstandingPayments to set
     */
    public void setHasOutstandingPayments(Boolean hasOutstandingPayments) {
        this.hasOutstandingPayments = hasOutstandingPayments;
    }

    /**
     * @return the outstandingInvoices
     */
    public List<Invoice> getOutstandingInvoices() {
        return outstandingInvoices;
    }

    /**
     * @param outstandingInvoices the outstandingInvoices to set
     */
    public void setOutstandingInvoices(List<Invoice> outstandingInvoices) {
        this.outstandingInvoices = outstandingInvoices;
    }

    /**
     * @return the loadPayments
     */
    public String getLoadPayments() {
        selectedCustomer = userSessionManagerBean.getCustomer();

        for (Invoice i : selectedCustomer.getCredit().getInvoices()) {
            Payment p = creditSessionBeanLocal.getPayment(i.getId());

            payments.add(p);
        }

        if (userSessionManagerBean.getSelectedPayment() != null) {
            selectedPayment = userSessionManagerBean.getSelectedPayment();

            userSessionManagerBean.setSelectedPayment(null);
        }

        return null;
    }

    /**
     * @param loadPayments the loadPayments to set
     */
    public void setLoadPayments(String loadPayments) {
        this.loadPayments = loadPayments;
    }

    /**
     * @return the selectedPayment
     */
    public Payment getSelectedPayment() {
        return selectedPayment;
    }

    /**
     * @param selectedPayment the selectedPayment to set
     */
    public void setSelectedPayment(Payment selectedPayment) {
        this.selectedPayment = selectedPayment;
    }

    public void go(ActionEvent event) {
        try {
            userSessionManagerBean.setCustomer(selectedCustomer);

            if (event.getComponent().getId().equals("btnGoToViewPayment")) {
                if (selectedReceipt != null) {
                    userSessionManagerBean.setSelectedPayment(selectedReceipt.getPayment());

                    FacesContext.getCurrentInstance().getExternalContext().redirect("http://"
                            + getUserSessionManagerBean().getServerName() + ":"
                            + getUserSessionManagerBean().getServerPort()
                            + "/MerlionERP-war/Web_Finance/payments.xhtml"); //redirect to payments.xhtml
                } else {
                    FacesContext.getCurrentInstance().addMessage(null,
                            new FacesMessage(FacesMessage.SEVERITY_ERROR, "Please select a receipt to view first.", ""));
                }
            } else if (event.getComponent().getId().equals("btnGoToViewInvoice")) {
                if (selectedPayment != null) {
                    userSessionManagerBean.setSelectedInvoice(selectedPayment.getInvoice());

                    FacesContext.getCurrentInstance().getExternalContext().redirect("http://"
                            + getUserSessionManagerBean().getServerName() + ":"
                            + getUserSessionManagerBean().getServerPort()
                            + "/MerlionERP-war/Web_Finance/invoices.xhtml"); //redirect to invoices.xhtml
                } else {
                    FacesContext.getCurrentInstance().addMessage(null,
                            new FacesMessage(FacesMessage.SEVERITY_ERROR, "Please select an invoice to view first.", ""));
                }
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            FacesContext.getCurrentInstance().addMessage(null,
                    new FacesMessage(FacesMessage.SEVERITY_ERROR, ex.toString(), ""));
        }
    }

    public void back(ActionEvent event) {
        try {
            if (event.getComponent().getId().equals("btnBackFromPayments")) {
                FacesContext.getCurrentInstance().getExternalContext().redirect("http://"
                        + getUserSessionManagerBean().getServerName() + ":"
                        + getUserSessionManagerBean().getServerPort()
                        + "/MerlionERP-war/Web_Sales/searchCustomer.xhtml?request=payments"); //redirect to searchCustomer.xhtml
            } else if (event.getComponent().getId().equals("btnBackFromInvoices")) {
                FacesContext.getCurrentInstance().getExternalContext().redirect("http://"
                        + getUserSessionManagerBean().getServerName() + ":"
                        + getUserSessionManagerBean().getServerPort()
                        + "/MerlionERP-war/Web_Sales/searchCustomer.xhtml?request=invoices"); //redirect to searchCustomer.xhtml
            } else if (event.getComponent().getId().equals("btnBackFromReceipts")) {
                FacesContext.getCurrentInstance().getExternalContext().redirect("http://"
                        + getUserSessionManagerBean().getServerName() + ":"
                        + getUserSessionManagerBean().getServerPort()
                        + "/MerlionERP-war/Web_Sales/searchCustomer.xhtml?request=receipts"); //redirect to searchCustomer.xhtml
            }
        } catch (Exception ex) {
            FacesContext.getCurrentInstance().addMessage(null,
                    new FacesMessage(FacesMessage.SEVERITY_ERROR, ex.toString(), ""));
        }
    }

    /**
     * @return the invoices
     */
    public List<Invoice> getInvoices() {
        return invoices;
    }

    /**
     * @param invoices the invoices to set
     */
    public void setInvoices(List<Invoice> invoices) {
        this.invoices = invoices;
    }

    /**
     * @return the selectedInvoice
     */
    public Invoice getSelectedInvoice() {
        return selectedInvoice;
    }

    /**
     * @param selectedInvoice the selectedInvoice to set
     */
    public void setSelectedInvoice(Invoice selectedInvoice) {
        this.selectedInvoice = selectedInvoice;
    }

    /**
     * @return the loadInvoices
     */
    public String getLoadInvoices() {
        selectedCustomer = userSessionManagerBean.getCustomer();

        List<PurchaseOrder> purchaseOrders = new ArrayList<PurchaseOrder>();
        purchaseOrders = salesOrderSessionBeanLocal.getPurchaseOrders(selectedCustomer.getCustId(), "Approved");

        for (PurchaseOrder po : purchaseOrders) {
            for (PurchaseItem pi : po.getPurchaseItems()) {
                List<Invoice> temp = creditSessionBeanLocal.getInvoices(pi.getId());

                invoices.addAll(temp);
            }
        }

        if (userSessionManagerBean.getSelectedInvoice() != null) {
            selectedInvoice = userSessionManagerBean.getSelectedInvoice();

            userSessionManagerBean.setSelectedInvoice(null);
        }

        return null;
    }

    /**
     * @param loadInvoices the loadInvoices to set
     */
    public void setLoadInvoices(String loadInvoices) {
        this.loadInvoices = loadInvoices;
    }

    /**
     * @return the receipts
     */
    public List<Receipt> getReceipts() {
        return receipts;
    }

    /**
     * @param receipts the receipts to set
     */
    public void setReceipts(List<Receipt> receipts) {
        this.receipts = receipts;
    }

    /**
     * @return the selectedReceipt
     */
    public Receipt getSelectedReceipt() {
        return selectedReceipt;
    }

    /**
     * @param selectedReceipt the selectedReceipt to set
     */
    public void setSelectedReceipt(Receipt selectedReceipt) {
        this.selectedReceipt = selectedReceipt;
    }

    /**
     * @return the loadReceipts
     */
    public String getLoadReceipts() {
        selectedCustomer = userSessionManagerBean.getCustomer();

        List<Payment> temp = new ArrayList<Payment>();

        for (Invoice i : selectedCustomer.getCredit().getInvoices()) {
            Payment p = creditSessionBeanLocal.getPayment(i.getId());

            if (p != null) {
                temp.add(p);
            }
        }

        for (Payment p : temp) {
            Receipt r = creditSessionBeanLocal.getReceipt(p.getId());

            receipts.add(r);
        }

        return null;
    }

    /**
     * @param loadReceipts the loadReceipts to set
     */
    public void setLoadReceipts(String loadReceipts) {
        this.loadReceipts = loadReceipts;
    }

    /**
     * @return the todayTimestamp
     */
    public Timestamp getTodayTimestampMinus30() {
        Calendar cal = Calendar.getInstance();
        cal.add(cal.DAY_OF_YEAR, -30);

        Timestamp ts = new Timestamp(cal.getTime().getTime());

        return ts;
    }

    /**
     * @param todayTimestamp the todayTimestamp to set
     */
    public void setTodayTimestampMinus30(Timestamp todayTimestampMinus30) {
        this.todayTimestampMinus30 = todayTimestampMinus30;
    }

    /**
     * @return the todayTimestampMinus7
     */
    public Timestamp getTodayTimestampMinus7() {
        Calendar cal = Calendar.getInstance();
        cal.add(cal.DAY_OF_YEAR, -7);

        Timestamp ts = new Timestamp(cal.getTime().getTime());

        return ts;
    }

    /**
     * @param todayTimestampMinus7 the todayTimestampMinus7 to set
     */
    public void setTodayTimestampMinus7(Timestamp todayTimestampMinus7) {
        this.todayTimestampMinus7 = todayTimestampMinus7;
    }

    /**
     * @return the loadOutstandingInvoices
     */
    public String getLoadOutstandingInvoices() {
        List<PurchaseOrder> purchaseOrders = new ArrayList<PurchaseOrder>();
        purchaseOrders = salesOrderSessionBeanLocal.getPurchaseOrders("Approved");

        for (PurchaseOrder po : purchaseOrders) {
            for (PurchaseItem pi : po.getPurchaseItems()) {
                List<Invoice> temp = creditSessionBeanLocal.getInvoices(pi.getId());

                for (Invoice i : temp) {
                    if (i.getStatus().equals("Pending Payment")) {
                        outstandingInvoices.add(i);
                    }
                }
            }
        }

        return null;
    }

    /**
     * @param loadOutstandingInvoices the loadOutstandingInvoices to set
     */
    public void setLoadOutstandingInvoices(String loadOutstandingInvoices) {
        this.loadOutstandingInvoices = loadOutstandingInvoices;
    }

    public void outstandingInvoicesOnRowSelect(SelectEvent event) {
        try {
            PurchaseOrder po = salesOrderSessionBeanLocal.getPurchaseOrderByPurchaseItem(selectedInvoice.getPurchaseItem().getId());

            selectedCustomer = po.getCustomer();

            userSessionManagerBean.setCustomer(selectedCustomer);
        } catch (Exception ex) {
            FacesContext.getCurrentInstance().addMessage(null,
                    new FacesMessage(FacesMessage.SEVERITY_ERROR, ex.toString(), ""));
        }
    }

    public void sendCreditReminder(ActionEvent event) {
        try {
            if (selectedInvoice != null && userSessionManagerBean.getCustomer() != null) {
                selectedCustomer = userSessionManagerBean.getCustomer();

                EmailManager em = new EmailManager();

                String subject = "Reminder to Settle Existing Invoice";
                String sender = "mf.merlionerp@gmail.com";
                String receiver = selectedCustomer.getEmail();
                String password = "merlionfood";

                String msg = "Dear " + selectedCustomer.getCompany() + ",\n\n";
                msg += "Please remember to settle your outstanding invoice. \n\n";
                msg += "Invoice in question is: ";

                msg += selectedInvoice.getId() + " ";

                msg += "\n\n";
                msg += "Regards,\n";
                msg += "Merlion Food Limited";

                System.out.println("Sending credit reminder to " + receiver + "...");

                em.sendEmail(subject, msg, sender, receiver, password);

                userSessionManagerBean.setCustomer(null);
                selectedInvoice = null;

                FacesContext.getCurrentInstance().getExternalContext().redirect("http://"
                        + getUserSessionManagerBean().getServerName() + ":"
                        + getUserSessionManagerBean().getServerPort()
                        + "/MerlionERP-war/Web_Finance/outstandingInvoices.xhtml"); //redirect to outstandingInvoices.xhtml
            } else {
                FacesContext.getCurrentInstance().addMessage(null,
                        new FacesMessage(FacesMessage.SEVERITY_ERROR, "Please select an invoice before continuing.", ""));
            }
        } catch (Exception ex) {
            FacesContext.getCurrentInstance().addMessage(null,
                    new FacesMessage(FacesMessage.SEVERITY_ERROR, ex.toString(), ""));
        }
    }

    /**
     * @return the creditRate
     */
    public Double getCreditRate() {
        return creditRate;
    }

    /**
     * @param creditRate the creditRate to set
     */
    public void setCreditRate(Double creditRate) {
        this.creditRate = creditRate;
    }
}
